// package com.zyx.order.server.config;
//
// import com.rabbitmq.client.Channel;
// import com.zyx.order.server.model.dto.OrderMessageDTO;
// import com.zyx.order.server.service.impl.OrderMessageService;
// import lombok.extern.slf4j.Slf4j;
// import org.jetbrains.annotations.NotNull;
// import org.springframework.amqp.core.*;
// import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
// import org.springframework.amqp.rabbit.connection.ConnectionFactory;
// import org.springframework.amqp.rabbit.connection.CorrelationData;
// import org.springframework.amqp.rabbit.core.RabbitAdmin;
// import org.springframework.amqp.rabbit.core.RabbitTemplate;
// import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
// import org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter;
// import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
// import org.springframework.amqp.support.converter.ClassMapper;
// import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
// import org.springframework.beans.factory.annotation.Autowired;
// import org.springframework.context.annotation.Bean;
// import org.springframework.context.annotation.Configuration;
//
// import java.io.IOException;
// import java.util.HashMap;
// import java.util.Map;
// import java.util.concurrent.TimeoutException;
//
// @Slf4j
// @Configuration
// public class RabbitConfig {
//
//     @Autowired
//     private OrderMessageService orderMessageService;
//
//     // 原生方法处理消息的消费
//     // @Autowired
//     // public void startListenMessage() throws IOException, TimeoutException, InterruptedException {
//     //     orderMessageService.handleMessage();
//     // }
//
//     /*==================================== restaurant ====================================*/
//     @Bean
//     public Exchange exchangeOrderRestaurant(){
//         return new DirectExchange("exchange.order.restaurant");
//     }
//     @Bean
//     public Queue queueOrder(){
//         return new Queue("queue.order");
//     }
//     @Bean
//     public Binding bindingOrderRestaurant(){
//         return new Binding("queue.order",
//                 Binding.DestinationType.QUEUE, "exchange.order.restaurant", "key.order", null);
//     }
//
//     /*==================================== deliveryman ====================================*/
//     @Bean
//     public Exchange exchangeOrderDeliveryman(){
//         return new DirectExchange("exchange.order.deliveryman");
//     }
//     @Bean
//     public Binding bindingOrderDeliveryman(){
//         return new Binding("queue.order",
//                 Binding.DestinationType.QUEUE, "exchange.order.deliveryman", "key.order", null);
//     }
//
//     /*==================================== settlement ====================================*/
//     @Bean
//     public Exchange exchangeOrderSettlement(){
//         return new FanoutExchange("exchange.order.settlement");
//     }
//     @Bean
//     public Exchange exchangeSettlementOrder(){
//         return new FanoutExchange("exchange.settlement.order");
//     }
//     @Bean
//     public Binding bindingSettlementOrder(){
//         return new Binding("queue.order",
//                 Binding.DestinationType.QUEUE, "exchange.settlement.order", "key.order", null);
//     }
//
//     /*==================================== reward ====================================*/
//     @Bean
//     public Exchange exchangeOrderReward(){
//         return new TopicExchange("exchange.order.reward");
//     }
//     @Bean
//     public Binding bindingOrderReward(){
//         return new Binding("queue.order",
//                 Binding.DestinationType.QUEUE, "exchange.order.reward", "key.order", null);
//     }
//
//     @Bean
//     public ConnectionFactory connectionFactory(){
//         CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
//         connectionFactory.setHost("81.68.117.201");
//         connectionFactory.setPort(5672);
//         connectionFactory.setPassword("guest");
//         connectionFactory.setUsername("guest");
//         // 如果需要开启发送确认和消息返回机制, 需要在connectionFactory设置下面参数
//         // 只在rabbitTemplate处设置会失效
//         connectionFactory.setPublisherConfirmType(CachingConnectionFactory.ConfirmType.CORRELATED);
//         connectionFactory.setPublisherReturns(true);
//         // 查看 RabbitAdmin的 afterPropertiesSet 方法, 会将initialize()方法添加到 ConnectionListener 中
//         // 也即是说只有回调了Connection, 才会执行initialize()方法
//         // 这里测试使用原生的channel进行consume, 并没有触发SpringBoot AMQP的回调
//         // 因此, 这里为了测试通过, 手动触发回调, 执行initialize()方法, 创建 Exchange、Queue、Binding
//         connectionFactory.createConnection();
//         return connectionFactory;
//     }
//
//     @Bean
//     public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory){
//         RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
//         // 开启自动创建 Exchange、Queue、Binding
//         rabbitAdmin.setAutoStartup(true);
//         return rabbitAdmin;
//     }
//
//     /**
//      * 定义 RabbitTemplate, 用于发送消息
//      */
//     @Bean
//     public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
//         RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
//         // 发送确认
//         rabbitTemplate.setMandatory(true);
//         rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
//             log.info("correlationData:{}, ack:{}, cause:{}",
//                     correlationData, ack, cause);
//         });
//         // 消息返回
//         rabbitTemplate.setReturnsCallback(ret -> {
//             log.info("message:{}, replyCode:{}, replyText:{}, exchange:{}, routingKey{}",
//                     ret.getMessage(), ret.getReplyCode(), ret.getReplyText(), ret.getExchange(), ret.getRoutingKey());
//         });
//         return rabbitTemplate;
//     }
//
//     /**
//      * ==================== 使用 SimpleMessageListenerContainer 监听消息 ====================
//      * ==================== 使用 MessageConverter ====================
//      * @see MessageListenerAdapter#onMessage(Message, Channel)
//      */
//     @Bean
//     public SimpleMessageListenerContainer messageListenerContainer(ConnectionFactory connectionFactory){
//         SimpleMessageListenerContainer messageListenerContainer = new SimpleMessageListenerContainer(connectionFactory);
//         messageListenerContainer.setQueueNames("queue.order");
//         messageListenerContainer.setConcurrentConsumers(3);
//         messageListenerContainer.setMaxConcurrentConsumers(5);
//
//         messageListenerContainer.setPrefetchCount(2);
//         messageListenerContainer.setAcknowledgeMode(AcknowledgeMode.MANUAL);
//
//         MessageListenerAdapter listenerAdapter = new MessageListenerAdapter(orderMessageService);
//         // 设置消息类型转换器
//         Jackson2JsonMessageConverter messageConverter = new Jackson2JsonMessageConverter();
//         messageConverter.setClassMapper(new ClassMapper() {
//             @Override
//             public void fromClass(@NotNull Class<?> aClass, @NotNull MessageProperties messageProperties) {
//             }
//
//             @NotNull
//             @Override
//             public Class<?> toClass(@NotNull MessageProperties messageProperties) {
//                 return OrderMessageDTO.class;
//             }
//         });
//         listenerAdapter.setMessageConverter(messageConverter);
//
//         // 指定队列对应的消费者处理方法， 如果没有设置， 默认使用handleMessage方法进行处理
//         Map<String, String> methodMap = new HashMap<>(1 << 3);
//         methodMap.put("queue.order", "handleMessage");
//         listenerAdapter.setQueueOrTagToMethodName(methodMap);
//         messageListenerContainer.setMessageListener(listenerAdapter);
//         return messageListenerContainer;
//     }
//
//     /*
//      * ==================== 使用 SimpleMessageListenerContainer 监听消息 ====================
//      * ==================== 不使用 MessageConverter ====================
//      * 使用 MessageListenerAdapter设置消息的消费
//      * @see MessageListenerAdapter#onMessage(Message, Channel)
//      */
//     // @Bean
//     // public SimpleMessageListenerContainer messageListenerContainer(ConnectionFactory connectionFactory){
//     //     SimpleMessageListenerContainer messageListenerContainer = new SimpleMessageListenerContainer(connectionFactory);
//     //     messageListenerContainer.setQueueNames("queue.order");
//     //     messageListenerContainer.setConcurrentConsumers(3);
//     //     messageListenerContainer.setMaxConcurrentConsumers(5);
//     //
//     //     messageListenerContainer.setPrefetchCount(2);
//     //     messageListenerContainer.setAcknowledgeMode(AcknowledgeMode.MANUAL);
//     //
//     //     MessageListenerAdapter listenerAdapter = new MessageListenerAdapter(orderMessageService);
//     //     // 显示指定委托类, 与上面构造方法等价
//     //     // MessageListenerAdapter listenerAdapter = new MessageListenerAdapter();
//     //     // listenerAdapter.setDelegate(orderMessageService);
//     //
//     //     // 指定队列对应的消费者处理方法， 如果没有设置， 默认使用handleMessage方法进行处理
//     //     Map<String, String> methodMap = new HashMap<>(1 << 3);
//     //     methodMap.put("queue.order", "handleMessage");
//     //     listenerAdapter.setQueueOrTagToMethodName(methodMap);
//     //     messageListenerContainer.setMessageListener(listenerAdapter);
//     //     return messageListenerContainer;
//     // }
//
//     /*
//      * ==================== 使用 SimpleMessageListenerContainer 监听消息 ====================
//      * 不使用 MessageListenerAdapter
//      */
//     // @Bean
//     // public SimpleMessageListenerContainer messageListenerContainer(ConnectionFactory connectionFactory){
//     //     SimpleMessageListenerContainer messageListenerContainer = new SimpleMessageListenerContainer(connectionFactory);
//     //     messageListenerContainer.setQueueNames("queue.order");
//     //     messageListenerContainer.setConcurrentConsumers(3);
//     //     messageListenerContainer.setMaxConcurrentConsumers(5);
//     //     // messageListenerContainer.setAcknowledgeMode(AcknowledgeMode.AUTO);
//     //     // messageListenerContainer.setMessageListener(new MessageListener() {
//     //     //     @Override
//     //     //     public void onMessage(Message message) {
//     //     //         log.info("message:{}", message);
//     //     //     }
//     //     // });
//     //     messageListenerContainer.setPrefetchCount(2);
//     //     messageListenerContainer.setAcknowledgeMode(AcknowledgeMode.MANUAL);
//     //     // 消费端消息确认
//     //     messageListenerContainer.setMessageListener(new ChannelAwareMessageListener() {
//     //         @Override
//     //         public void onMessage(Message message, Channel channel) throws Exception {
//     //             log.info("=====>>>>> message:{}", message);
//     //             channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
//     //         }
//     //     });
//     //     return messageListenerContainer;
//     // }
//
//
//     /* ==================== ConnectionFactory、RabbitAdmin、Exchange、Queue、Binding 耦合的初始化方法 ==================== */
//     // @Autowired
//     // public void initRabbit() {
//     //     CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
//     //     connectionFactory.setHost("81.68.117.201");
//     //     connectionFactory.setPort(5672);
//     //     connectionFactory.setPassword("guest");
//     //     connectionFactory.setUsername("guest");
//     //
//     //     RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
//     //
//     //     /*==================== restaurant ====================*/
//     //     rabbitAdmin.declareExchange(new DirectExchange("exchange.order.restaurant"));
//     //     rabbitAdmin.declareQueue(new Queue("queue.order"));
//     //     rabbitAdmin.declareBinding(new Binding("queue.order",
//     //             Binding.DestinationType.QUEUE, "exchange.order.restaurant", "key.order", null));
//     //
//     //     /*==================== deliveryman ====================*/
//     //     rabbitAdmin.declareExchange(new DirectExchange("exchange.order.deliveryman"));
//     //     rabbitAdmin.declareBinding( new Binding("queue.order",
//     //             Binding.DestinationType.QUEUE, "exchange.order.deliveryman", "key.order", null));
//     //
//     //     /*==================== settlement ====================*/
//     //     rabbitAdmin.declareExchange(new FanoutExchange("exchange.order.settlement"));
//     //     rabbitAdmin.declareExchange(new FanoutExchange("exchange.settlement.order"));
//     //     rabbitAdmin.declareBinding( new Binding("queue.order",
//     //             Binding.DestinationType.QUEUE, "exchange.order.settlement", "key.order", null));
//     //
//     //     /*==================== reward ====================*/
//     //     rabbitAdmin.declareExchange(new TopicExchange("exchange.order.reward"));
//     //     rabbitAdmin.declareBinding(new Binding("queue.order",
//     //             Binding.DestinationType.QUEUE, "exchange.order.reward", "key.order", null));
//     // }
//
//
// }
